/**
 * CaddieProductController.java 21 juil. 07
 *
 * Copyright (c) 2007 windu.2b <jcaddie@windu2b.org>. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.windu2b.jcaddie.swing;

import java.util.*;

import javax.swing.*;
import javax.swing.undo.*;

import org.windu2b.jcaddie.model.*;

/**
 * @author windu.2b
 * 
 */
public class CaddieProductController
{
	private Caddie	            caddie;


	private UndoableEditSupport	undoSupport;


	private ResourceBundle	    resource;


	private JComponent	        caddieView;




	public CaddieProductController( Caddie caddie, UserPreferences preferences,
	        UndoableEditSupport undoSupport )
	{
		this.caddie = caddie;
		this.undoSupport = undoSupport;
		this.resource = ResourceBundle.getBundle( CaddieProductController.class
		        .getName() );
		this.caddieView = new CaddieProductPane( caddie, preferences, this );
		( ( CaddieProductPane ) caddieView ).displayView();
	}




	public JComponent getView()
	{
		return caddieView;
	}




	/**
	 * Controls the modification of selected product.
	 */
	public void modifySelection()
	{
		final List<Object> oldSelection = caddie.getSelectedItems();
		List<CaddiePieceOfProduct> selectedProduct = Caddie
		        .getProductSubList( oldSelection );
		if ( !selectedProduct.isEmpty() )
		{
			CaddieProductPane productPanel = ( CaddieProductPane ) getView();
			final String name = productPanel.getProductName();

			// Create an array of modified product with their current
			// properties values
			final ModifiedPieceOfProduct[] modifiedProduct = new ModifiedPieceOfProduct[selectedProduct
			        .size()];
			for ( int i = 0; i < modifiedProduct.length; i++ )
			{
				modifiedProduct[i] = new ModifiedPieceOfProduct(
				        selectedProduct.get( i ) );
			}
			// Apply modification
			doModifyProduct( modifiedProduct, name );
			if ( this.undoSupport != null )
			{
				UndoableEdit undoableEdit = new AbstractUndoableEdit()
				{
					/**
					 * 
					 */
					private static final long	serialVersionUID	= 0L;




					@Override
					public void undo() throws CannotUndoException
					{
						super.undo();
						undoModifyProduct( modifiedProduct );
						caddie.setSelectedItems( oldSelection );
					}




					@Override
					public void redo() throws CannotRedoException
					{
						super.redo();
						doModifyProduct( modifiedProduct, name );
						caddie.setSelectedItems( oldSelection );
					}




					@Override
					public String getPresentationName()
					{
						return resource.getString( "undoModifyProductName" );
					}
				};
				this.undoSupport.postEdit( undoableEdit );
			}
		}
	}




	/**
	 * Modifies product properties with the values in parameter.
	 */
	private void doModifyProduct( ModifiedPieceOfProduct[] modifiedProduct,
	        String name )
	{
		for ( ModifiedPieceOfProduct modifiedPiece : modifiedProduct )
		{
			CaddiePieceOfProduct piece = modifiedPiece.getPieceOfProduct();
			caddie.setPieceOfProductName( piece, name != null ? name : piece
			        .getName() );
		}
	}




	/**
	 * Restores product properties from the values stored in
	 * <code>modifiedFurnitures</code>.
	 */
	private void undoModifyProduct( ModifiedPieceOfProduct[] modifiedProduct )
	{
		for ( ModifiedPieceOfProduct modifiedPiece : modifiedProduct )
		{
			CaddiePieceOfProduct piece = modifiedPiece.getPieceOfProduct();
			caddie.setPieceOfProductName( piece, modifiedPiece.getName() );
		}
	}



	/**
	 * Stores the current properties values of a modified piece of product.
	 */
	private static final class ModifiedPieceOfProduct
	{
		private final CaddiePieceOfProduct	piece;


		private final String		       name;




		public ModifiedPieceOfProduct( CaddiePieceOfProduct piece )
		{
			this.piece = piece;
			this.name = piece.getName();
		}




		public CaddiePieceOfProduct getPieceOfProduct()
		{
			return piece;
		}




		/**
		 * @return the name
		 */
		public String getName()
		{
			return name;
		}




		/**
		 * @return the piece
		 */
		public CaddiePieceOfProduct getPiece()
		{
			return piece;
		}
	}
}